package com.fa4j.system.file.controller;

import com.fa4j.common.base.exception.CommonRequestError;
import com.fa4j.common.base.model.Page;
import com.fa4j.common.base.model.RemoveCmd;
import com.fa4j.common.web.annotation.ApiMethod;
import com.fa4j.common.web.model.AppType;
import com.fa4j.system.file.model.SysFile;
import com.fa4j.system.file.model.SysFileQuery;
import com.fa4j.system.file.model.SysFileUploadCmd;
import com.fa4j.system.file.repository.SysFileRepository;
import com.fa4j.system.file.service.SysFileService;
import com.fa4j.system.login.util.LoginUtil;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("system/file")
@RequiredArgsConstructor
public class SysFileController {

    private final SysFileService sysFileService;
    private final SysFileRepository sysFileRepository;

    @ApiMethod(name = "系统文件-分页查询", type = AppType.MANAGE)
    @GetMapping("page")
    public Page<SysFile> page(SysFileQuery query) {
        Page<SysFile> result = sysFileRepository.queryPage(query);
        result.getRecords().forEach(sysFileService::setFileUrl);
        return result;
    }

    @ApiMethod(name = "系统文件-详情查询", type = AppType.MANAGE)
    @GetMapping("{id}")
    public SysFile detail(@PathVariable Long id) {
        return sysFileRepository.findById(id)
                .map(sysFileService::setFileUrl)
                .orElseThrow(() -> CommonRequestError.NOT_FOUND.build("系统文件"));
    }

    @ApiMethod(name = "系统文件-删除", type = AppType.MANAGE)
    @DeleteMapping("{id}")
    public SysFile remove(@PathVariable Long id) {
        return sysFileService.remove(RemoveCmd.of(id, LoginUtil.getAccountId()));
    }

    @ApiMethod(name = "系统文件-下载", type = AppType.MANAGE, auth = ApiMethod.Switch.OFF)
    @GetMapping("download/{fileId}")
    public void download(@PathVariable("fileId") Long fileId, HttpServletResponse response) throws IOException {
        SysFile sysFile = sysFileRepository.findById(fileId).orElseThrow(() -> CommonRequestError.NOT_FOUND.build("文件"));
        response.setContentType(sysFile.getContentType());
        String fileName = URLEncoder.encode(sysFile.getFileName(), StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        sysFileService.download(sysFile, response.getOutputStream());
    }

    @ApiMethod(name = "系统文件-上传", type = AppType.MANAGE, auth = ApiMethod.Switch.OFF)
    @PostMapping("upload/{fileGroup}")
    public SysFile upload(@PathVariable("fileGroup") String fileGroup, @RequestPart("file") MultipartFile file) throws IOException {
        return sysFileService.upload(buildUploadCmd(fileGroup, file));
    }

    private @Valid SysFileUploadCmd buildUploadCmd(String fileGroup, MultipartFile file) throws IOException {
        SysFileUploadCmd cmd = new SysFileUploadCmd();
        cmd.setFileGroup(fileGroup);
        cmd.setFileName(file.getOriginalFilename());
        cmd.setFileSize(file.getSize());
        cmd.setContentType(file.getContentType());
        cmd.setInputStream(file.getInputStream());
        cmd.setOperatorId(LoginUtil.getAccountId());
        return cmd;
    }

    @ApiMethod(name = "系统文件-批量上传", type = AppType.MANAGE, auth = ApiMethod.Switch.OFF)
    @PostMapping("batchUpload/{fileGroup}")
    public List<SysFile> batchUpload(@PathVariable("fileGroup") String fileGroup, @RequestPart("files") MultipartFile[] files) throws IOException {
        List<SysFile> fileList = new ArrayList<>();
        for (MultipartFile file : files) {
            fileList.add(sysFileService.upload(buildUploadCmd(fileGroup, file)));
        }
        return fileList;
    }

}
